import asyncio
import os
import subprocess

import aiohttp
import requests


# 获取 m3u8 文件
def down_m3u8():
    """
    定义函数，用于下载 m3u8 文件
    """
    m3u8_url = 'https://cdn13.tvtvgood.com/202408/07/efddd1922ec7/playlist.m3u8?token=QPi4FQppMtYIX-9aLKkx3w&expires=1723976953'
    m3u8_resp = requests.get(m3u8_url)  # 发送 GET 请求获取 m3u8 文件内容
    with open('userTv/playList.m3u8', 'w') as f:  # 以写入模式打开文件
        f.write(m3u8_resp.text)  # 将获取的内容写入文件
    print("m3u8 down ok")  # 打印下载成功的消息


# 获取所有 ts 文件
async def get_ts():
    """
    定义函数，用于获取所有的 ts 文件
    """
    task = []
    with open('userTv/playList.m3u8', 'r') as f:  # 以读模式打开 m3u8 文件
        for i in f:  # 遍历文件中的每一行
            ts = i.strip()  # 去除行两端的空格和换行符
            if ts.startswith("#"):  # 如果行以'#'开头，跳过
                continue
            url = f"https://cdn13.tvtvgood.com/202408/07/efddd1922ec7/{ts}"  # 构建 ts 文件的 URL
            task.append(down_ts(url, ts))  # 调用下载 ts 文件的函数
    await asyncio.wait(task)


# 下载 ts 文件
async def down_ts(ts_url, ts):
    """
    定义函数，用于下载单个 ts 文件
    :param ts_url: ts 文件的 URL
    :param ts: ts 文件的名称
    """
    async with aiohttp.ClientSession() as session:
        async with session.get(ts_url) as ts_resp:
            with open(f'userTv/video/{ts}', mode='wb') as f:
                f.write(await ts_resp.content.read())  # 读取内容是异步的，需要await挂起
                f.flush()

    print(f"{ts} ok")


# 合并所有 ts 文件
def merge_ts_files():
    """
    定义函数，用于合并所有的 ts 文件
    """
    pwd = 'E://PyCharm 2023.1.6//userData//pyDemo//main//爬虫知识点//4_多线程爬虫//userTv//video//'
    output_file = 'userTv/merged.mp4'  # 合并后的输出文件路径
    ts_list = os.listdir('userTv/video')  # 获取 ts 文件列表
    ts_pwd = [os.path.join(pwd, i) for i in ts_list]  # 构建完整的文件路径列表
    # 构建 ffmpeg 命令
    command = ['ffmpeg', '-i', 'concat:' + '|'.join(ts_pwd), '-c', 'copy', output_file]
    # 执行命令
    subprocess.run(command)
    print("ok")  # 打印合并成功的消息


if __name__ == '__main__':
    # 下载m3u8文件
    down_m3u8()
    # 开启异步协程快速下载ts文件
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(get_ts())
    # 合并ts文件
    merge_ts_files()
